#coding=utf-8
################################################################
#           Load and unpack CIFAR-10 python version            #
# from https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz #
#                                                              #
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!  #
#            Run this scipt with python2 only                  #
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!  #
################################################################
# 现在是在python3下使用

import pickle
import numpy as np

# CIFAR-10原始数据集存放的文件夹名称，该文件夹应放在此子项目文件夹之下，即"PrepareCIFAR-10\cifar-10-batches-py"
batches_dir = 'cifar-10-batches-py' 

def unpickle(fname):
	# pickle.load，将文件中的数据解析为一个Python对象
    fo = open(fname, 'rb')
    d = pickle.load(fo, encoding='iso-8859-1')
    fo.close()

	# reshape, 
	# param1：待reshape的数组，
	# param2：reshape后的shape形状，这里具体的意思是，reshape后的样子在第一阶不知道有多少个，但第一阶下的每一个元素的形状是(32,32,3)，这是因为CIFAR-10的每张图片是32*32尺寸的3波段彩图
	# param3：读取待reshape的数组也就是param1中的元素的索引顺序，可以是'C'、'F'、'A'。
    data = np.reshape(d['data'], [-1, 32, 32, 3], order='F') 

	# transpose，对张量的元素按阶的顺序调整位置，原始的阶顺序是(0,1,2,3)，这里调整成(0,2,1,3)
    data = np.transpose(data, [0, 2, 1, 3])

	# 再次reshape，成为一个矩阵，这个矩阵的一个阶表示图的数量，另一个阶表示每张图的像素值数量，也就是32*32*3
    data = np.reshape(data, [-1, 32*32*3])

	# array，创建一个数组，来源是param1，也就是d['labels']，这里作为标签存起来
    labels = np.array(d['labels'], dtype='int8')
    return data, labels

for x in range(1, 6):
    fname = batches_dir + '/data_batch_' + str(x)
    data, labels = unpickle(fname)
    if x == 1:
        train_images = data
        train_labels = labels
    else:
		# vstack，垂直把两个形参代表的数组堆叠起来
        train_images = np.vstack((train_images, data))
		# concatenate，把两个形参代表的数组串联起来
        train_labels = np.concatenate((train_labels, labels))

# 验证集的图和标签
validation_images, validation_labels = unpickle(batches_dir + '/test_batch')

print(train_images.shape, validation_images.shape)
print(train_labels.shape, validation_labels.shape)

# savez_compressed，将数组压缩保存为文件，
# 第一个数组起名为'train_images'，训练数据
# 第二个数组起名为'validation_images'，验证数据
# 第三个数组起名为'train_labels'，训练标签
# 第四个数组起名为'validation_labels'，验证标签
np.savez_compressed('cifar', train_images=train_images, validation_images=validation_images,
                    train_labels=train_labels, validation_labels=validation_labels)
